package cn.codexin.wechatofficial.service;

import cn.codexin.wechatofficial.dto.MyTemplateMessageDTO;
import cn.codexin.wechatofficial.dto.TemplateMessageDTO;
import cn.codexin.wechatofficial.dto.TemplateMessageDataDTO;
import cn.codexin.wechatofficial.mapper.HTDB.dbo.AccessTokenMapper;
import cn.codexin.wechatofficial.mapper.HTDB.dbo.CommonMapper;
import cn.codexin.wechatofficial.mapper.HTDB.dbo.RealTimeMapper;
import cn.codexin.wechatofficial.mapper.HTDB.dbo.StationMapper;
import cn.codexin.wechatofficial.model.dbo.*;
import cn.codexin.wechatofficial.wechat.WeChatProvider;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author ：zhanfan
 * @date ：Created in 2020/9/14 14:53
 */

@Service
@Slf4j
public class WarnService {

    @Autowired
    private RealTimeService realTimeService;

    @Autowired
    private RealTimeMapper realTimeMapper;

    @Autowired
    private CommonMapper commonMapper;

    @Autowired
    private AccessTokenMapper accessTokenMapper;

    @Value("${wechat.template-message-id}")
    private String template_id;

    public void sendMVWarn() {
        List<Integer> moduleIDList = commonMapper.getAllModuleIDs();
        //存储当前遥测告警设备的dotID
        HashSet<Integer>nowMvAlarmSet=new HashSet<>();
        //获取上次遥测告警的HashSet文件
        HashSet<Integer>mvAlarmSet=new HashSet<>();
        String mvPath="mvAlarmSet.txt";
        File mvFile = new File(mvPath);
        if(mvFile.exists()){
            mvAlarmSet=readFile(mvFile);
            mvFile.delete();
        }
        //存储当前遥信告警设备的dotID
        HashSet<Integer>nowSPSAlarmSet=new HashSet<>();
        //获取上次遥信告警的HashSet文件
        HashSet<Integer>spsAlarmSet=new HashSet<>();
        String spsPath="spsAlarmSet.txt";
        File spsFile = new File(spsPath);
        if(spsFile.exists()){
            spsAlarmSet=readFile(spsFile);
            spsFile.delete();
        }
        //逐房间发送告警信息
        for (int moduleID : moduleIDList) {
            int stationID = commonMapper.getSubstationIDByModuleID(moduleID);
            List<String> openidList = commonMapper.getOpenidListByStationID(stationID);
            //发送遥测告警信息
            List<MVIndexPojo> mvAlarmList = realTimeService.MVAlarm(moduleID);
            for (MVIndexPojo mvAlarm : mvAlarmList) {
                //不告警则跳过
                if (!mvAlarm.isWarn()) continue;
                //存储到当前告警的HashSet中
                nowMvAlarmSet.add(mvAlarm.getDotID());
                //上次已告警则跳过
                if(!mvAlarmSet.isEmpty()&&mvAlarmSet.contains(mvAlarm.getDotID())) continue;
                //获取报警位置信息
                AlarmLocation alarmLocation = realTimeMapper.locationById(mvAlarm.getDotID(), "MVDef");
                for (String mvOpenid : openidList) {
                    //组装模板消息
                    TemplateMessageDTO mvWarnDTO = getWarnDTO(mvOpenid);
                    MyTemplateMessageDTO mvWarnDataDTO = getMVWarnDataDTO(mvAlarm, alarmLocation);
                    mvWarnDTO.setData(mvWarnDataDTO);
                    log.info(postWarnDTO(mvWarnDTO));
                }
            }

            //发送遥信告警信息
            List<SPSAlarm> spsAlarmList = realTimeService.SPSAlarm(moduleID);
            for (SPSAlarm spsAlarm : spsAlarmList) {
                //不告警则跳过
                if (!spsAlarm.isWarn()) continue;
                //存储到当前告警的HashSet中
                nowSPSAlarmSet.add(spsAlarm.getDotID());
                //上次已告警则跳过
                if(!spsAlarmSet.isEmpty()&&spsAlarmSet.contains(spsAlarm.getDotID())) continue;
                //获取报警位置信息
                AlarmLocation alarmLocation = realTimeMapper.locationById(spsAlarm.getDotID(), "SPSDef");
                for (String spsOpenid : openidList) {
                    //组装模板消息
                    TemplateMessageDTO spsWarnDTO = getWarnDTO(spsOpenid);
                    MyTemplateMessageDTO mvWarnDataDTO = getSPSWarnDataDTO(spsAlarm, alarmLocation);
                    spsWarnDTO.setData(mvWarnDataDTO);
                    log.info(postWarnDTO(spsWarnDTO));
                }
            }
        }

        //写当前遥测告警的HashSet文件
        writeFile(nowMvAlarmSet,mvFile);
        //写当前遥信告警的HashSet文件
        writeFile(nowSPSAlarmSet,spsFile);
    }

    public HashSet<Integer> readFile(File file) {
        HashSet<Integer>set=new HashSet<>();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file),"UTF-8"));
            String lineTxt = null;
            while ((lineTxt = br.readLine()) != null) {
                Integer x = Integer.valueOf(lineTxt);
                set.add(x);
//                System.out.println(x);
            }
            br.close();
            log.info("read HashSet: "+set);
        } catch (Exception e) {
            log.info("read errors :" + e);
        }
        return set;
    }

    public void writeFile(HashSet<Integer> set,File file){
        try {
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
            for (Integer num : set) {
                bw.write(num.toString());
                bw.newLine();
            }
            bw.close();
        } catch (Exception e) {
            log.error("write errors :" + e);
        }
    }

    private TemplateMessageDTO getWarnDTO(String openid) {
        //点击模板消息后的跳转页面,上线服务器后修改
        String redirectUrl = "http://www.jiushengwx.com/CurrentWarning";
        TemplateMessageDTO warnDTO = new TemplateMessageDTO();
        warnDTO.setTouser(openid);
        warnDTO.setTemplate_id(template_id);
        warnDTO.setUrl(redirectUrl);
        return warnDTO;
    }

    private MyTemplateMessageDTO getMVWarnDataDTO(MVIndexPojo mvAlarm, AlarmLocation alarmLocation) {
        MyTemplateMessageDTO warnDataDTO = new MyTemplateMessageDTO();
        //告警描述
        TemplateMessageDataDTO title = new TemplateMessageDataDTO();
        title.setValue("遥测设备报警! 报警数据：" + mvAlarm.getValue() + mvAlarm.getUnit());
        //告警时间
        TemplateMessageDataDTO time = new TemplateMessageDataDTO();
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        time.setValue(dateFormat.format(date));
        //告警地点
        TemplateMessageDataDTO location = new TemplateMessageDataDTO();
        location.setValue(alarmLocation.getAreaName() + " " + alarmLocation.getSubstationName() + " " + alarmLocation.getIedName());
        //告警设备名称
        TemplateMessageDataDTO name = new TemplateMessageDataDTO();
        name.setValue(mvAlarm.getDotName());
        //告警原因
        TemplateMessageDataDTO reason = new TemplateMessageDataDTO();
        reason.setValue(mvAlarm.getDesc());
        //负责人
        TemplateMessageDataDTO contact = new TemplateMessageDataDTO();
        contact.setValue("请联系相关负责人");
        //告警备注
        TemplateMessageDataDTO remark = new TemplateMessageDataDTO();
        remark.setValue("请及时关注报警信息并尽快处理");
        warnDataDTO.setFirst(title)
                .setKeyword1(time)
                .setKeyword2(location)
                .setKeyword3(name)
                .setKeyword4(reason)
                .setKeyword5(contact)
                .setRemark(remark);
        return warnDataDTO;
    }

    private MyTemplateMessageDTO getSPSWarnDataDTO(SPSAlarm spsAlarm, AlarmLocation alarmLocation) {
        MyTemplateMessageDTO warnDataDTO = new MyTemplateMessageDTO();
        //告警描述
        TemplateMessageDataDTO title = new TemplateMessageDataDTO();
        title.setValue("遥信设备报警!");
        //告警时间
        TemplateMessageDataDTO time = new TemplateMessageDataDTO();
        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        time.setValue(dateFormat.format(date));
        //告警地点
        TemplateMessageDataDTO location = new TemplateMessageDataDTO();
        location.setValue(alarmLocation.getAreaName() + " " + alarmLocation.getSubstationName() + " " + alarmLocation.getIedName());
        //告警设备名称
        TemplateMessageDataDTO name = new TemplateMessageDataDTO();
        name.setValue(spsAlarm.getDotName());
        //告警原因
        TemplateMessageDataDTO reason = new TemplateMessageDataDTO();
        reason.setValue("遥信设备触发报警");
        //负责人
        TemplateMessageDataDTO contact = new TemplateMessageDataDTO();
        contact.setValue("请联系相关负责人");
        //告警备注
        TemplateMessageDataDTO remark = new TemplateMessageDataDTO();
        remark.setValue("请及时关注报警信息并尽快处理");
        warnDataDTO.setFirst(title)
                .setKeyword1(time)
                .setKeyword2(location)
                .setKeyword3(name)
                .setKeyword4(reason)
                .setKeyword5(contact)
                .setRemark(remark);
        return warnDataDTO;
    }

    private String postWarnDTO(TemplateMessageDTO warnDTO) {
        //获取access_token
        String token = accessTokenMapper.selectByExample(new AccessTokenExample()).get(0).getAccessToken();
        OkHttpClient client = new OkHttpClient();
        MediaType mediaType = MediaType.get("application/json; charset=utf-8");
        String json = JSON.toJSONString(warnDTO);
        System.out.println(json);
        RequestBody body = RequestBody.create(json, mediaType);
        Request request = new Request.Builder()
                .url("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + token)
                .post(body)
                .build();
        try (Response response = client.newCall(request).execute()) {
            return Objects.requireNonNull(response.body()).string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "error";
    }
}
